var apiHandler = require('../services/api-handler'),
    ideas = require('../services/ideas'),
    ideaModel = require('../models/idea'),
    commentModel = require('../models/comment'),
    voteModel = require('../models/vote'),
    users = require('../models/user'),
    abuses = require('../models/abuse'),
    activity = require('../models/activity'),
    keywordModel = require('../models/keyword'),
    knowledgeModel = require('../models/knowledge'),
    async = require('async'),
    mailer = require('../mailer/mailer'),
    util = require('../helpers/util'),
    config = require('../config/config'),
    Client = require('node-rest-client').Client,
    combinations = require('combinations');

user = require('../models/user');

var client = new Client();

var args = {
    headers: {"Content-Type": "application/json", "API_KEY": process.env.NLP_API_KEY}
};

function getStringCount(str, val) {

    var patt1 = /[`1234567890-=/~!@#$%^&*()_{}+:";'<>?,./]/g;
    val = val.replace(patt1, "");

    if ((val.indexOf("[")) >= 0) {
        val = val.replace('[', '');
        val = val.replace('[', '');
        val = val.replace('[', '');
        val = val.replace('[', '');
    }
    if ((val.indexOf("]")) >= 0) {
        val = val.replace(']', '');
        val = val.replace(']', '');
        val = val.replace(']', '');
        val = val.replace(']', '');
    }
    if ((val.indexOf("\n")) >= 0) {
        val.replace('\n', '');
        val.replace('\n', '');
        val.replace('\n', '');
        val.replace('\n', '');
    }

    var regExp = new RegExp(val, "gi");

    return (str.match(regExp) || []).length;
}

function getFilteredSentences(str, values) {
    var sentences = str.split(/[.|!|?]\s/gi);
    var temp = [];
    if (sentences) {
        for (var i = 0; i < sentences.length; i++) {
            var tempkey = [];
            for (var j = 0; j < values.length; j++) {
                var count = getStringCount(sentences[i], values[j].content);
                if (count > 0) {
                    var knowledge = {};
                    knowledge.id = values[j].id;
                    knowledge.content = values[j].content;
                    tempkey.push(knowledge);
                }
            }
            if (tempkey.length > 0) {
                var tempSentence = {};
                tempSentence.content = sentences[i];
                tempSentence.keyword = tempkey;
                temp.push(tempSentence);
            }
        }
    }
    return temp;
}

exports.createIdea = function (req, res) {
    var bodyParams = req.body;
    bodyParams.user = req.user;
    var complexContent = "";
    async.waterfall([
            //Extract Complex Idea
            function (done) {
                if (bodyParams.content.indexOf("<cited>") > 0) {
                    complexContent = bodyParams.content;
                }

                bodyParams.content = bodyParams.content.replace("<cited>", "");
                bodyParams.content = bodyParams.content.replace("</cited>", "");
                bodyParams.content = bodyParams.content.replace("<citation>", "");

                var tempTags = bodyParams.tags


                var tempTagResult = []

                tempTags.forEach(function (item, index) {
                    if (item.indexOf("(") != -1 && item.indexOf(")") != -1) {
                        item = item.split("(")[0]
                        tempTagResult.push(item)
                    } else {
                        tempTagResult.push(item)
                    }
                })

                bodyParams.tags = tempTagResult


                done("");
            },
            //Create Idea Modal To Be Saved
            function (done) {
                var idea = new ideaModel(bodyParams);
                if (complexContent != "") {
                    idea.complex = complexContent;
                }
                if (bodyParams.tags && bodyParams.tags.length > 0) {
                    ideas.addTags(bodyParams.tags).then(function (result) {
                        if (!result.length) {
                            done("", idea)
                        }
                    });
                } else {
                    done("", idea);
                }
            },
            //Save New Basic Idea
            function (idea, done) {
                ideas.createIdea(idea).then(function (result) {
                    if (!result) {
                        apiHandler.setErrorResponse('IDEA_CREATION_FAILED', res);
                    } else {
                        // To capture activity
                        var newActivity = new activity({
                            activityType: "Idea created",
                            idea: idea._id,
                            user: req.user
                        });
                        activity.createNewActivity(newActivity, apiHandler.handler.check(res, 'ACTIVITY_FAILED', function (activity) {
                            done("", idea);
                        }));
                        apiHandler.setSuccessResponse(idea, res);
                    }
                });
            }
            //Get Keywords from API
           /* function (idea, done) {
                args.data = {};
                args.data.text = bodyParams.cloudContent;

                client.post(process.env.NLP_API_URL, args, function (data, response) {
                    // parsed response body as js object
                    var resultKeyword = [];
                    if (data && data.response && data.response.data && data.response.data.keywords) {
                        resultKeyword = data.response.data.keywords;
                    }
                    // raw response
                    var newResult = [];
                    for (var i = 0; i < resultKeyword.length; i++) {
                        if (resultKeyword[i].toString().trim() !== '') {
                            newResult.push(resultKeyword[i]);
                        }
                    }
                    resultKeyword = newResult;
                    delete newResult;
                    var keywordId = [];
                    async.eachSeries(resultKeyword, function (elementOfArray, callback) {
                        var keyword = new keywordModel();
                        keyword.content = elementOfArray[0];
                        keyword.count = getStringCount(bodyParams.content, keyword.content);
                        keyword.user.push(bodyParams.user._id);

                        var tempKey = {};
                        tempKey.count = keyword.count;
                        tempKey.content = keyword.content;


                        keywordModel.findAndCreate(keyword, bodyParams.user._id, function (err, result) {
                            tempKey.id = result._id;
                            keywordId.push(tempKey);
                            callback();
                        })
                    }, function (err) {
                        done("", idea, keywordId);
                    });
                });
            },*/
            //Save Keyword reference in Idea table
            /*function (idea, keywordId, done) {
                var sentences = getFilteredSentences(bodyParams.cloudContent, keywordId);
                sentences.forEach(function (elementOfArray) {
                    var knowledge = new knowledgeModel();
                    knowledge.content = elementOfArray.content;
                    knowledge.keyword = elementOfArray.keyword;
                    knowledge.ideaId = idea._id;
                    knowledgeModel.createKnowledge(knowledge, function (err, result) {
                    });
                });

                ideaModel.getIdeaById(idea._id, apiHandler.handler.check(res, 'NO_IDEAS', function (updateIdea) {
                    apiHandler.setSuccessResponse(idea, res);
                    if (keywordId && keywordId.length) {
                        for (var i = 0; i < keywordId.length; i++) {
                            updateIdea.citationArray.push(keywordId[i].content);
                        }
                        updateIdea.keyword = keywordId;
                        updateIdea.save();
                        done("");
                    }
                }));
            }*/
        ],
        function (err) {
        });
};

exports.editIdea = function (req, res) {
    ideaModel.getIdeaById(req.body.ideaId, apiHandler.handler.check(res, 'NO_IDEAS', function (idea) {
        var bodyParams = req.body;
        if (bodyParams.tags) {
            idea.tags = [];
            bodyParams.tags.map(function (tag) {
                idea.tags.push(tag);
            });
        }
        if (bodyParams.title) {
            idea.title = bodyParams.title;
        }
        if (bodyParams.content) {
            idea.content = bodyParams.content;
        }
        if (bodyParams.keyword) {
            for (var i = 0; i < bodyParams.keyword.length; i++) {
                var newKeyword = {
                    "content": bodyParams.keyword[i]
                };
                idea.keyword.push(newKeyword);
            }
        }
        if (bodyParams.citation) {
            idea.citation = bodyParams.citation;
        }
        if (bodyParams.citationArray) {
            idea.citationArray = [];
            for (var i = 0; i < bodyParams.citationArray.length; i++) {
                var newKeyword = bodyParams.citationArray[i];
                idea.citationArray.push(newKeyword);
            }
        }
        idea.save(apiHandler.handler.check(res, 'IDEA_UPDATE_FAILED', function (success) {
            apiHandler.setSuccessResponse('', res);
        }));
    }));
};

exports.getIdea = function (req, res) {

    var t1 = new Date().getTime()


    ideaModel.getIdea(req.user._id, req.user, req.body, apiHandler.handler.check(res, 'NO_IDEAS', function (idea) {
        var t2 = new Date().getTime()
        if (!idea || idea.length == 0) {
            var data = {
                ideaList: [],
                ideaCount: 0
            };
            apiHandler.setSuccessResponse(data, res);
        }
        else {
            ideaModel.getFilteredIdeaCount(req.body, apiHandler.handler.check(res, 'NO_IDEAS', function (ideaCount) {
                var t3 = new Date().getTime()
                var data = {
                    ideaList: idea,
                    ideaCount: ideaCount[0].count
                };
                apiHandler.setSuccessResponse(data, res);
            }));
        }
    }));
};

exports.getTitle = function (req, res) {
    ideaModel.getTitle(req.body.title, apiHandler.handler.check(res, 'NO_IDEAS', function (title) {
        apiHandler.setSuccessResponse(title, res);

    }));
};

exports.getTags = function (req, res) {
    var key = req.body.tags;
    ideaModel.getTags(key, apiHandler.handler.check(res, 'NO_IDEAS', function (more) {
        if (!more) {
            apiHandler.setErrorResponse('NO_IDEAS', res);
        } else {
            apiHandler.setSuccessResponse(more, res);
        }
    }));
};

exports.favouriteIdea = function (req, res) {
    if (req.body.favouriteType == 'addFavourite') {
        ideaModel.addFavoriteIdea(req.user, req.body.ideaId, apiHandler.handler.check(res, 'NO_IDEAS', function (idea) {
            if (idea) {
                var newActivity = new activity({
                    activityType: "Favourite",
                    idea: req.body.ideaId,
                    user: req.user
                });
                activity.createNewActivity(newActivity, apiHandler.handler.check(res, 'ACTIVITY_FAILED', function (activity) {
                    apiHandler.setSuccessResponse('', res);

                }));
            }
            else {
                apiHandler.setErrorResponse('ALREADY_ADDED_TO_FAVORITE', res);
            }
        }));
    }
    else if (req.body.favouriteType == 'removeFavourite') {
        ideaModel.removeFavoriteIdea(req.user, req.body.ideaId, apiHandler.handler.check(res, 'ACTIVITY_FAILED', function (idea) {
            apiHandler.setSuccessResponse('', res);
        }));
    }
    else {
        apiHandler.setErrorResponse('FAVORITE_TYPE_ERROR', res);
    }
};

exports.recentIdeasByUser = function (req, res) {
    var data;
    ideaModel.recentIdeasByUser(req.user._id, req.body, apiHandler.handler.check(res, 'NO_IDEAS', function (idea) {
        if (!idea || idea.length == 0) {
            data = {
                ideaList: [],
                ideaCount: 0
            };
            apiHandler.setSuccessResponse(data, res);
        } else {
            data = {
                ideaList: idea,
                ideaCount: idea.length
            };
            apiHandler.setSuccessResponse(data, res);
        }
    }));
};

exports.getLeadBoardStats = function (req, res) {
    ideaModel.getLeaderBoardStats(req.body, apiHandler.handler.check(res, 'NO_IDEAS', function (stats) {
        if (!stats) {
            apiHandler.setErrorResponse('NO_STATS');
        } else {
            apiHandler.setSuccessResponse(stats, res);
        }
    }));
};

exports.getDashBoardStats = function (req, res) {
    ideaModel.getAllIdeaCount(apiHandler.handler.check(res, 'NO_IDEAS', function (ideaCount) {
        ideaModel.getUserIdeaCount(req.user._id, apiHandler.handler.check(res, 'NO_IDEAS', function (uIdeaCount) {
            commentModel.getAllCommentCount(apiHandler.handler.check(res, 'NO_COMMENT_FOUND', function (commentCount) {
                commentModel.getUserCommentCount(req.user._id, apiHandler.handler.check(res, 'NO_COMMENT_FOUND', function (uCommentCount) {
                    var data = {
                        totalIdeaCount: ideaCount,
                        userIdeaCount: uIdeaCount,
                        totalCommentCount: commentCount,
                        userCommentCount: uCommentCount
                    };
                    apiHandler.setSuccessResponse(data, res);
                }));
            }));
        }));
    }));
};

exports.getSpam = function (req, res) {
    abuses.getAbuseById(req.body.abuseId, apiHandler.handler.check(res, 'NO_ABUSE', function (ABUSE) {
        ideaModel.getSpam(ABUSE.idea, apiHandler.handler.check(res, 'NO_IDEAS', function (IDEA) {
            users.getUserById(IDEA.user, apiHandler.handler.check(res, 'NO_USERS', function (iUser) {
                users.getUserById(ABUSE.user, apiHandler.handler.check(res, 'NO_USERS', function (aUser) {
                    if (req.body.status == "Approved") {
                        apiHandler.setSuccessResponse('', res);
                        ABUSE.status = "Approved";
                        ABUSE.save();
                        mailer.sendAbuseApproveMail(iUser, aUser, IDEA, ABUSE)
                            .then(function (success) {
                            })
                            .catch(function (err) {
                                apiHandler.setErrorResponse('ERROR_WHILE_MAIL_SENDING', res);
                            });
                    } else {
                        apiHandler.setSuccessResponse('', res);
                        ABUSE.status = "Rejected";
                        ABUSE.save();
                        mailer.sendAbuseRejectMail(iUser, aUser, IDEA, ABUSE, req.body.adminReason)
                            .then(function (success) {
                            })
                            .catch(function (err) {
                                apiHandler.setErrorResponse('ERROR_WHILE_MAIL_SENDING', res);
                            });
                    }
                }));
            }));
        }));
    }));
};

exports.getOneIdea = function (req, res) {
    ideaModel.getIdeaById(req.body.ideaId, apiHandler.handler.check(res, 'NO_IDEAS', function (idea) {
        ideaModel.getOneIdea(idea, req.body.userId, apiHandler.handler.check(res, 'NO_IDEAS', function (Idea) {
            apiHandler.setSuccessResponse(Idea[0], res);
        }));
    }));
};

exports.deleteIdea = function (req, res) {
    console.log('req.body.ideaId', req.body.ideaId);
    ideaModel.getIdeaById(req.body.ideaId, apiHandler.handler.check(res, 'NO_IDEAS', function (IDEA) {
        if (!IDEA) {
            apiHandler.setErrorResponse('NO_IDEAS', res);
        } else {
            ideaModel.deleteIdea(req.body.ideaId, function (err, idea) {
                if (!err) {
                    commentModel.deleteCommentsByIdea(req.body.ideaId, function (err, comment) {
                    });
                    voteModel.deleteVotesByIdea(req.body.ideaId, function (err, Vote) {
                    });
                    activity.deleteActivitiesByIdea(req.body.ideaId, function (err, Activity) {
                    });
                    abuses.deleteAbuseByIdea(req.body.ideaId, function (err, Abuse) {
                    });
                    apiHandler.setSuccessResponse('', res);
                } else {
                    apiHandler.setErrorResponse('ERROR_WHILE_DELETING_DATA', res);
                }
            });
        }
    }));
};

exports.getCitableKeywords = function (req, res) {
    var sentence = req.body.content;
    var wordsArray = sentence.split(" ");
    keywordModel.findKeywordsByWords(wordsArray, apiHandler.handler.check(res, 'NO_KEYWORDS', function (keywords) {
        var tempKeywordids = [];
        for (var i = 0; i < keywords.length; i++) {
            var count = getStringCount(sentence, keywords[i].content);
            if (count > 0) {
                tempKeywordids.push(keywords[i]._id);
                var rep = "<cited>" + keywords[i].content + "</cited>";
                sentence = sentence.replace(keywords[i].content, rep)
            }
        }
        apiHandler.setSuccessResponse(sentence, res);
    }));
};

/*exports.autoCompleteByKnowledge = function (req, res) {
    var sentence = req.body.content, data;
    console.log(req.body.content)
    console.log(data)
    console.log(sentence)
    knowledgeModel.autoCompleteByKnowledge(sentence, apiHandler.handler.check(res, 'NO_KNOWLEDGE', function (autoComplete) {
        console.log(autoComplete)
        let data = {
            'autoComplete': autoComplete,
            'sentence': [],
            'showCount': 0
        };
        apiHandler.setSuccessResponse(data, res);



    }));
};*/


exports.autoCompleteByKnowledge = function (req, res) {

    var sentence = req.body.content; //用户当前输入
    req.body.wholeContent = sentence; //用户当前输入

    var finalData = {
        'autoComplete': [],
        'sentence': [],
        'showCount': ""
    };


    async.waterfall([
        // 抽取并返回自动提示关键词
        function (done) {

            var wordsArray = [];
            if (req.body.wholeContent) {
                var wholeSentence = req.body.wholeContent;
                wordsArray = wholeSentence.split(" ");
            }
            var i,
                j,
                tempArray,
                finalArray = [],
                bigArray = [],
                smallArray = [],
                chunk = 15;
            for (i = 0, j = wordsArray.length; i < j; i += chunk) {
                tempArray = wordsArray.slice(i, i + chunk);
                // do whatever
                bigArray.push(combinations(tempArray));
            }
            for (var a = 0; a < bigArray.length; a++) {
                smallArray = bigArray[a];
                for (var b = 0; b < smallArray.length; b++) {
                    var eachArray = smallArray[b];
                    var elem = '';
                    for (var c = 0; c < eachArray.length; c++) {
                        if (c == 0) {
                            elem = elem.concat(eachArray[c]);
                        } else {
                            elem = elem.concat(' ');
                            elem = elem.concat(eachArray[c]);
                        }
                    }
                    finalArray.push(elem);
                }


                keywordModel.getKeyWordArea({}, apiHandler.handler.check(res, 'NO_KEYWORDS', function (totalIdeaList) {


                        var totalIdeaCount = []

                        totalIdeaList.forEach(function (item, index) {
                            totalIdeaCount.push(item._id)
                        })


                        keywordModel.findKeywordsByWords(finalArray, apiHandler.handler.check(res, 'NO_KEYWORDS', function (keywords) {
                            var keywordNew = [],
                                showCount = 0;


                            if (keywords != 'undefined' && keywords && keywords.length > 0) {
                                for (var i = 0; i < keywords.length; i++) {
                                    if (wholeSentence && wholeSentence.length > 0) {
                                        var count = getStringCount(wholeSentence, keywords[i].content);
                                    } else {
                                        var count = 0;
                                    }
                                    for (var x = count; x > 0; x--) {
                                        if (wholeSentence.indexOf(keywords[i].content) >= 0) {
                                            keywordNew.push(keywords[i]);
                                            showCount += keywords[i].count;
                                        }
                                    }
                                }




                                finalData = {
                                    'sentence': keywordNew,
                                    'showCount': showCount
                                };


                                var sentenceSize = finalData.sentence.length

                                finalData.sentence.forEach(function (item, index) {
                                    // let totalUserNum = userData[0].total
                                    if(totalIdeaCount.indexOf(item.count) == -1){
                                        item.red = false
                                        item.percent = 0
                                    }else{
                                        item.red = ((totalIdeaCount.indexOf(item.count) + 1)/ totalIdeaCount.length) < 0.1
                                        item.percent = ((1 - ((totalIdeaCount.indexOf(item.count)/ totalIdeaCount.length)))*100).toFixed(2)
                                    }


                                    /*if (index == (sentenceSize - 1)) {
                                        done(data)
                                        // apiHandler.setSuccessResponse(data, res);
                                    }*/


                                })

                            } else {finalData = {
                                    'sentence': '',
                                    'showCount': ''
                                };
                               /* done(data)*/
                            }

                            done("")

                        }));
                    }))
            }
            
        },
        // 从knowlege中抽取匹配的内容，按照ABC，BC，AB，AC，C，B，A的顺序进行匹配
        // 首先抽取ABC
        function (done) {

            var temp = sentence.trim().split(" ")
            // 首先找出匹配ABC匹配的内容
            var querySentence = "\\b"

            temp.forEach(function (item, index) {
                querySentence += "(" + item + "\\b)|"
            })

            querySentence = querySentence.substring(0, querySentence.length -1)

            knowledgeModel.autoCompleteByKnowledge(querySentence, apiHandler.handler.check(res, 'NO_KNOWLEDGE', function (autoComplete) {

                // 如果查找结果大于10条，则按照优先级顺序取前10条
                if(autoComplete && autoComplete.length > 10){


                    // 首先找出匹配ABC匹配的内容
                    var abcPattern = ".*\\b"

                    temp.forEach(function (item, index) {
                        abcPattern += "(" + item + ")+\\b.*"
                    })

                    var bcPattern = `.*\\b(${temp[1]})+.*\\b(${temp[2]})+.*\\b";`
                    var abPattern = `.*\\b(${temp[0]})+.*\\b(${temp[1]})+.*\\b";`
                    var acPattern = `.*\\b(${temp[0]})+.*\\b(${temp[2]})+.*\\b";`



                    var sentenceScoreMap = []

                    /**
                     * ABC 1000000
                     * BC 100000
                     * AB 10000
                     * AC 1000
                     * C 100
                     * B 10
                     * A 1
                     */


                    for(var i = 0; i< autoComplete.length; i++){

                        var score = 0

                        var singleItem = autoComplete[i].content
                        if(singleItem.match(abcPattern) != null){
                            // 如果能够匹配得到
                            //tempResultList.push(singleItem)
                            score += 10000000

                        }
                        if(singleItem.match(bcPattern) != null){
                            score += 100000
                        }
                        if(singleItem.match(abPattern) != null){
                            score += 10000
                        }
                        if(singleItem.match(acPattern) != null){
                            score += 1000
                        }
                        if(singleItem.indexOf(temp[2]) != -1){
                            score += 100
                        }
                        if(singleItem.indexOf(temp[1]) != -1){
                            score += 10
                        }
                        if(singleItem.indexOf(temp[0]) != -1){
                            score += 1
                        }
                        sentenceScoreMap.push({
                            index: i,
                            score: score
                        })
                    }

                    // sort 求前10排名的推荐内容
                    sentenceScoreMap.sort(function (a, b) {
                       return b.score - a.score
                    })

                    var finalCompleteList = []

                    for(var i =0; i< 10; i++){
                        finalCompleteList.push(autoComplete[sentenceScoreMap[i].index])
                    }
                    finalData.autoComplete = finalCompleteList


                }else{
                    // 如果小于10条，则可以直接返回

                    finalData.autoComplete =  autoComplete

                }

                done("", finalData)
            }))


        },
        function (result, done) {
            // 处理成功返回
            apiHandler.setSuccessResponse(result, res);
        }
    ],function(error){

        finalData = {
            'autoComplete': '',
            'sentence': '',
            'showCount': ''
        };
        // 出错返回空数据
        apiHandler.setSuccessResponse(finalData, res);
        
    })
    


};


exports.getKnowledeByKeywords = function (req, res) {
    var keyword = req.body.content;
    knowledgeModel.getKnowledgeListByKeyword(keyword, apiHandler.handler.check(res, 'NO_KNOWLEDGE', function (knowledgeList) {
        apiHandler.setSuccessResponse(knowledgeList, res);
    }));
};

exports.getCitationTreeData = function (req, res) {
    if (!req.body.content) {
        apiHandler.setErrorResponse('REQUIRED_FIELDS_MISSING', res);
    } else {
        var input;
        if (req.body.date) {
            input = {
                content: req.body.content,
                date: req.body.date
            };
        } else {
            input = {
                content: req.body.content
            };
        }
        var stringInput = '';

        for (var x = 0; x < req.body.content.length; x++) {
            if (x == 0) {
                stringInput = req.body.content[x];
            } else {
                stringInput = stringInput + ', ' + req.body.content[x];
            }
        }
        stringInput = '[' + stringInput + ']';

        ideaModel.getCitationTreeData(input, apiHandler.handler.check(res, 'NO_IDEAS', function (result) {
            if (result && result.length > 0) {
                if (req.body.content.length == 2) {
                    var finalOutput = singleTreeRecursion(result, req.body.content.length);
                    finalOutput.input = stringInput;
                } else {
                    var finalOutput = multipleTreeRecursion(result, req.body.content.length);
                    finalOutput.input = stringInput;
                }
                apiHandler.setSuccessResponse(finalOutput, res);
            }
        }));
    }
};

function multipleTreeRecursion(result, keywordLength) {
    for (var j = 1; j < result.length; j++) {
        var date0 = new Date(result[0].createdAt),
            dateJ = new Date(result[j].createdAt);

        if (result[0].size <= result[j].size && date0 <= dateJ) {
            var found = 0;
            for (var iKey = 0; iKey < result[0].keyword.length; iKey++) {
                if (result[j].keyword.indexOf(result[0].keyword[iKey]) >= 0) {
                    found++;
                }
            }
            if (result[0].keyword.length == found) {
                if (!result[j].children) {
                    result[j].children = [];
                }
                result[j].children.push(result[0]);
                break;
            }
        }
    }

    if (result.length > 1) {
        result.splice(0, 1);
    }
    if (result.length > 1) {
        return multipleTreeRecursion(result, keywordLength);
    } else {
        if (result.length > 0) {
            var iterationOne = result[0];
            var tree;
            if (keywordLength == 1) {
                tree = multipleTreeGenerateLastTreeObject(iterationOne);
                return multipleTreeLastGetChildNodes(tree);
            } else {
                tree = multipleTreeGenerateTreeObject(iterationOne);
                return multipleTreeGetChildNodes(tree);
            }
        }
    }
};

function multipleTreeGenerateTreeObject(iterationOne) {
    var tree = {};
    tree._id = iterationOne._id;
    tree.createdAt = iterationOne.createdAt;
    tree.keyword = [];
    tree.keyword = iterationOne.keyword;
    tree.user = iterationOne.user;
    tree.userName = iterationOne.userName;
    tree.size = iterationOne.size;

    tree.children = [];

    if (iterationOne.children && iterationOne.children.length > 0) {
        for (var j = 0; j < iterationOne.children.length; j++) {
            var x = {};

            x._id = iterationOne.children[j]._id;
            x.createdAt = iterationOne.children[j].createdAt;
            x.keyword = [];
            x.keyword = iterationOne.children[j].keyword;
            x.user = iterationOne.children[j].user;
            x.userName = iterationOne.children[j].userName;
            x.size = iterationOne.children[j].size;

            if (iterationOne.children[j].children === 0) {
                x.callMe = false;
            } else {
                x.callMe = true;
            }
            x.children = [];

            tree.children.push(x);
        }
    } else {
        tree.children = [];
    }
    return tree;
};

function multipleTreeGetChildNodes(parent) {
    var temp = {text: "", image: "", children: []};
    if (parent) {

        var temp1 = {name: "", title: "", contact: ""};
        temp1.id = parent._id;
        temp1.userId = parent.user;
        temp1.name = parent.userName;
        var x = util.getFormattedDate(parent.createdAt);
        x = x.replace("-", "/");
        x = x.replace("-", "/");
        temp1.title = x;
        var y = parent.keyword.join(', ');
        temp1.contact = '[' + y + ']';
        temp.text = temp1;
        temp.stackChildren = true;
        if (parent.userImage) {
            temp.image = process.env.PROFILE_URL + parent.userImage.split(".")[1] + '.' + parent.userImage.split(".")[2];
        } else {
            temp.image = process.env.PROFILE_URL + "/profileUploads/default.png";
        }

        if (parent.children) {

            for (var i = 0; i < parent.children.length; i++) {
                var temp2 = {name: "", title: "", contact: ""};
                temp2.id = parent.children[i]._id;
                temp2.userId = parent.children[i].user;
                temp2.name = parent.children[i].userName;
                var x = util.getFormattedDate(parent.children[i].createdAt);
                x = x.replace("-", "/");
                x = x.replace("-", "/");
                temp2.title = x;
                var y = parent.children[i].keyword.join(', ');
                temp2.contact = '[' + y + ']';
                var temp3 = {};
                temp3.text = temp2;
                temp3.stackChildren = false;
                temp3.children = [];
                temp3.callMe = parent.children[i].callMe;
                if (parent.userImage) {
                    temp3.image = process.env.PROFILE_URL + parent.children[i].userImage.split(".")[1] + '.' + parent.children[i].userImage.split(".")[2];
                } else {
                    temp3.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                }
                temp.children.push(temp3);
            }
        } else {
            var temp1 = {name: "", title: "", contact: ""};
            temp1.id = parent._id;
            temp1.userId = parent.user;
            temp1.name = parent.userName;
            var x = util.getFormattedDate(parent.createdAt);
            x = x.replace("-", "/");
            x = x.replace("-", "/");
            temp1.title = x;
            var y = parent.keyword[0];
            temp1.contact = '[' + y + ']';
            temp.text = temp1;
            temp.stackChildren = true;
            if (parent.userImage) {
                temp.image = process.env.PROFILE_URL + parent.userImage.split(".")[1] + '.' + parent.userImage.split(".")[2];
            } else {
                temp.image = process.env.PROFILE_URL + "/profileUploads/default.png";
            }
        }
    }
    return temp;
};

function multipleTreeGenerateLastTreeObject(iterationOne) {
    var tree = {};
    tree._id = iterationOne._id;
    tree.createdAt = iterationOne.createdAt;
    tree.keyword = [];
    tree.keyword = iterationOne.keyword;
    tree.user = iterationOne.user;
    tree.userName = iterationOne.userName;
    tree.size = iterationOne.size;

    tree.children = [];

    if (iterationOne.children && iterationOne.children.length > 0) {

        var x = {};

        x._id = iterationOne.children[0]._id;
        x.createdAt = iterationOne.children[0].createdAt;
        x.keyword = [];
        x.keyword = iterationOne.children[0].keyword;
        x.user = iterationOne.children[0].user;
        x.userName = iterationOne.children[0].userName;
        x.size = iterationOne.children[0].size;

        x.children = [];

        if (iterationOne.children[0].children && iterationOne.children[0].children.length > 0) {
            var newArray = iterationOne.children[0].children[0];

            var x1 = {};

            x1._id = newArray._id;
            x1.createdAt = newArray.createdAt;
            x1.keyword = [];
            x1.keyword = newArray.keyword;
            x1.user = newArray.user;
            x1.userName = newArray.userName;
            x1.size = newArray.size;

            x1.children = [];

            if (iterationOne.children[0].children[0].children && iterationOne.children[0].children[0].children.length > 0) {
                var newArray1 = iterationOne.children[0].children[0].children[0];

                var x2 = {};

                x2._id = newArray1._id;
                x2.createdAt = newArray1.createdAt;
                x2.keyword = [];
                x2.keyword = newArray1.keyword;
                x2.user = newArray1.user;
                x2.userName = newArray1.userName;
                x2.size = newArray1.size;

                x2.children = [];

                if (iterationOne.children[0].children[0].children[0].children && iterationOne.children[0].children[0].children[0].children.length > 0) {
                    var newArray2 = iterationOne.children[0].children[0].children[0].children[0];

                    var x3 = {};

                    x3._id = newArray2._id;
                    x3.createdAt = newArray2.createdAt;
                    x3.keyword = [];
                    x3.keyword = newArray2.keyword;
                    x3.user = newArray2.user;
                    x3.userName = newArray2.userName;
                    x3.size = newArray2.size;

                    x3.children = [];

                    x2.children.push(x3);
                }
                x1.children.push(x2);
            }
            x.children.push(x1);
        } else {
            tree.children = [];
        }


        tree.children.push(x);

    } else {
        tree.children = [];
    }
    return tree;
};

function multipleTreeLastGetChildNodes(parent) {
    var temp = {text: "", image: "", children: []};
    if (parent) {

        var temp1 = {name: "", title: "", contact: ""};
        temp1.id = parent._id;
        temp1.userId = parent.user;
        temp1.name = parent.userName;
        var x = util.getFormattedDate(parent.createdAt);
        x = x.replace("-", "/");
        x = x.replace("-", "/");
        temp1.title = x;
        var y = parent.keyword.join(', ');
        temp1.contact = '[' + y + ']';
        temp.text = temp1;
        temp.stackChildren = true;
        if (parent.userImage) {
            temp.image = process.env.PROFILE_URL + parent.userImage.split(".")[1] + '.' + parent.userImage.split(".")[2];
        } else {
            temp.image = process.env.PROFILE_URL + "/profileUploads/default.png";
        }

        if (parent.children && parent.children.length > 0) {
            var temp2 = {name: "", title: "", contact: ""};
            temp2.id = parent.children[0]._id;
            temp2.userId = parent.children[0].user;
            temp2.name = parent.children[0].userName;
            var x = util.getFormattedDate(parent.children[0].createdAt);
            x = x.replace("-", "/");
            x = x.replace("-", "/");
            temp2.title = x;
            var y = parent.children[0].keyword.join(', ');
            temp2.contact = '[' + y + ']';
            var temp3 = {};
            temp3.text = temp2;
            temp3.stackChildren = false;
            temp3.children = [];
            temp3.callMe = parent.children[0].callMe;
            if (parent.userImage) {
                temp3.image = process.env.PROFILE_URL + parent.children[0].userImage.split(".")[1] + '.' + parent.children[0].userImage.split(".")[2];
            } else {
                temp3.image = process.env.PROFILE_URL + "/profileUploads/default.png";
            }

            if (parent.children[0].children && parent.children[0].children.length > 0) {
                var newParent = parent.children[0].children[0];
                var temp4 = {name: "", title: "", contact: ""};
                temp4.id = newParent._id;
                temp4.userId = newParent.user;
                temp4.name = newParent.userName;
                var x = util.getFormattedDate(newParent.createdAt);
                x = x.replace("-", "/");
                x = x.replace("-", "/");
                temp4.title = x;
                var y = newParent.keyword.join(', ');
                temp4.contact = '[' + y + ']';
                var temp5 = {};
                temp5.text = temp4;
                temp5.stackChildren = false;
                temp5.children = [];
                temp5.callMe = newParent.callMe;
                if (newParent.userImage) {
                    temp5.image = process.env.PROFILE_URL + newParent.userImage.split(".")[1] + '.' + newParent.userImage.split(".")[2];
                } else {
                    temp5.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                }
                if (parent.children[0].children[0].children && parent.children[0].children[0].children.length > 0) {
                    var newParent1 = parent.children[0].children[0].children[0];
                    var temp6 = {name: "", title: "", contact: ""};
                    temp6.id = newParent1._id;
                    temp6.userId = newParent1.user;
                    temp6.name = newParent1.userName;
                    var x = util.getFormattedDate(newParent1.createdAt);
                    x = x.replace("-", "/");
                    x = x.replace("-", "/");
                    temp6.title = x;
                    var y = newParent1.keyword.join(', ');
                    temp6.contact = '[' + y + ']';
                    var temp7 = {};
                    temp7.text = temp6;
                    temp7.stackChildren = false;
                    temp7.children = [];
                    temp7.callMe = newParent1.callMe;
                    if (newParent1.userImage) {
                        temp7.image = process.env.PROFILE_URL + newParent1.userImage.split(".")[1] + '.' + newParent1.userImage.split(".")[2];
                    } else {
                        temp7.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                    }
                    if (parent.children[0].children[0].children[0].children && parent.children[0].children[0].children[0].children.length > 0) {
                        var newParent2 = parent.children[0].children[0].children[0].children[0];
                        var temp8 = {name: "", title: "", contact: ""};
                        temp8.id = newParent2._id;
                        temp8.userId = newParent2.user;
                        temp8.name = newParent2.userName;
                        var x = util.getFormattedDate(newParent2.createdAt);
                        x = x.replace("-", "/");
                        x = x.replace("-", "/");
                        temp8.title = x;
                        var y = newParent2.keyword.join(', ');
                        temp8.contact = '[' + y + ']';
                        var temp9 = {};
                        temp9.text = temp8;
                        temp9.stackChildren = false;
                        temp9.children = [];
                        temp9.callMe = newParent2.callMe;
                        if (newParent2.userImage) {
                            temp9.image = process.env.PROFILE_URL + newParent2.userImage.split(".")[1] + '.' + newParent2.userImage.split(".")[2];
                        } else {
                            temp9.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                        }
                        temp7.children.push(temp9);
                    } else {
                        parent.children[0].children[0].children[0].children = [];
                    }
                    temp5.children.push(temp7);
                } else {
                    parent.children[0].children[0].children = [];
                }
                temp3.children.push(temp5);
            } else {
                parent.children[0].children = [];
            }
            temp.children.push(temp3);
        } else {
            parent.children = [];
        }
    }
    return temp;
};

function singleTreeRecursion(result, keywordLength) {
    for (var j = 1; j < result.length; j++) {

        var date0 = new Date(result[0].createdAt),
            dateJ = new Date(result[j].createdAt);

        if (result[0].size <= result[j].size && date0 <= dateJ) {
            var found = 0;
            for (var iKey = 0; iKey < result[0].keyword.length; iKey++) {
                if (result[j].keyword.indexOf(result[0].keyword[iKey]) >= 0) {
                    found++;
                }
            }
            if (result[0].keyword.length == found) {
                if (!result[j].children) {
                    result[j].children = [];
                }
                result[j].children.push(result[0]);

                break;
            }
        }
    }

    if (result.length > 2) {
        result.splice(0, 1);
    }
    if (result.length > 2) {
        return singleTreeRecursion(result, keywordLength);
    } else {

        if (result.length > 0) {
            var tree;
            var iterationOne = result[0];
            if (keywordLength == 2) {
                tree = SingleTreeGenerateTreeObject(iterationOne);
                return singleTreeGetChildNodes(tree);
            } else if (keywordLength == 1) {
                tree = multipleTreeGenerateLastTreeObject(iterationOne);
                return multipleTreeLastGetChildNodes(tree);
            } else {
                tree = multipleTreeGenerateTreeObject(iterationOne);
                return multipleTreeGetChildNodes(tree);
            }
        }
    }
};

function SingleTreeGenerateTreeObject(iterationOne) {
    var tree = {};
    tree._id = iterationOne._id;
    tree.createdAt = iterationOne.createdAt;
    tree.keyword = [];
    tree.keyword = iterationOne.keyword;
    tree.user = iterationOne.user;
    tree.userName = iterationOne.userName;
    tree.size = iterationOne.size;

    tree.children = [];

    if (iterationOne.children && iterationOne.children.length > 0) {
        var loop1 = iterationOne.children;
        for (var a = 0; a < loop1.length; a++) {
            var x = {};

            x._id = iterationOne.children[a]._id;
            x.createdAt = iterationOne.children[a].createdAt;
            x.keyword = [];
            x.keyword = iterationOne.children[a].keyword;
            x.user = iterationOne.children[a].user;
            x.userName = iterationOne.children[a].userName;
            x.size = iterationOne.children[a].size;

            x.children = [];

            if (iterationOne.children[a].children && iterationOne.children[a].children.length > 0) {
                var loop2 = iterationOne.children[a].children;
                for (var b = 0; b < loop2.length; b++) {
                    var newArray = iterationOne.children[a].children[b];
                    var x1 = {};

                    x1._id = newArray._id;
                    x1.createdAt = newArray.createdAt;
                    x1.keyword = [];
                    x1.keyword = newArray.keyword;
                    x1.user = newArray.user;
                    x1.userName = newArray.userName;
                    x1.size = newArray.size;

                    x1.children = [];

                    if (iterationOne.children[a].children[b].children && iterationOne.children[a].children[b].children.length > 0) {
                        var loop3 = iterationOne.children[a].children[b].children;
                        for (var c = 0; c < loop3.length; c++) {
                            var newArray1 = iterationOne.children[a].children[b].children[c];

                            var x2 = {};

                            x2._id = newArray1._id;
                            x2.createdAt = newArray1.createdAt;
                            x2.keyword = [];
                            x2.keyword = newArray1.keyword;
                            x2.user = newArray1.user;
                            x2.userName = newArray1.userName;
                            x2.size = newArray1.size;

                            x2.children = [];

                            if (iterationOne.children[a].children[b].children[c].children && iterationOne.children[a].children[b].children[c].children.length > 0) {
                                var loop4 = iterationOne.children[a].children[b].children[c].children;
                                for (var d = 0; d < loop4.length; d++) {
                                    var newArray2 = iterationOne.children[a].children[b].children[c].children[d];
                                    var x3 = {};

                                    x3._id = newArray2._id;
                                    x3.createdAt = newArray2.createdAt;
                                    x3.keyword = [];
                                    x3.keyword = newArray2.keyword;
                                    x3.user = newArray2.user;
                                    x3.userName = newArray2.userName;
                                    x3.size = newArray2.size;

                                    x3.children = [];

                                }
                            }
                        }
                    }
                    if (x2)
                        x2.children.push(x3);
                    x1.children.push(x2);
                    x.children.push(x1);
                }
            } else {
                tree.children = [];
            }


            tree.children.push(x);

        }
    } else {
        tree.children = [];
    }
    return tree;
};

function singleTreeGetChildNodes(parent) {
    var temp = {text: "", image: "", children: []};
    if (parent) {

        var temp1 = {name: "", title: "", contact: ""};
        temp1.id = parent._id;
        temp1.userId = parent.user;
        temp1.name = parent.userName;
        var x = util.getFormattedDate(parent.createdAt);
        x = x.replace("-", "/");
        x = x.replace("-", "/");
        temp1.title = x;
        var y = parent.keyword.join(', ');
        temp1.contact = '[' + y + ']';
        temp.text = temp1;
        temp.stackChildren = true;
        if (parent.userImage) {
            temp.image = process.env.PROFILE_URL + parent.userImage.split(".")[1] + '.' + parent.userImage.split(".")[2];
        } else {
            temp.image = process.env.PROFILE_URL + "/profileUploads/default.png";
        }


        if (parent.children && parent.children.length > 0) {
            var loop11 = parent.children;
            for (var p = 0; p < loop11.length; p++) {
                var temp2 = {name: "", title: "", contact: ""};
                temp2.id = parent.children[p]._id;
                temp2.userId = parent.children[p].user;
                temp2.name = parent.children[p].userName;
                var x = util.getFormattedDate(parent.children[p].createdAt);
                x = x.replace("-", "/");
                x = x.replace("-", "/");
                temp2.title = x;
                var y = parent.children[p].keyword.join(', ');
                temp2.contact = '[' + y + ']';
                var temp3 = {};
                temp3.text = temp2;
                temp3.stackChildren = false;
                temp3.children = [];
                temp3.callMe = parent.children[p].callMe;
                if (parent.userImage) {
                    temp3.image = process.env.PROFILE_URL + parent.children[p].userImage.split(".")[1] + '.' + parent.children[p].userImage.split(".")[2];
                } else {
                    temp3.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                }

                if (parent.children[p].children && parent.children[p].children.length > 0) {
                    var loop12 = parent.children[p].children;
                    for (var q = 0; q < loop12.length; q++) {
                        var newParent = parent.children[p].children[q];
                        var temp4 = {name: "", title: "", contact: ""};
                        temp4.id = newParent._id;
                        temp4.userId = newParent.user;
                        temp4.name = newParent.userName;
                        var x = util.getFormattedDate(newParent.createdAt);
                        x = x.replace("-", "/");
                        x = x.replace("-", "/");
                        temp4.title = x;
                        var y = newParent.keyword.join(', ');
                        temp4.contact = '[' + y + ']';
                        var temp5 = {};
                        temp5.text = temp4;
                        temp5.stackChildren = false;
                        temp5.children = [];
                        temp5.callMe = newParent.callMe;
                        if (newParent.userImage) {
                            temp5.image = process.env.PROFILE_URL + newParent.userImage.split(".")[1] + '.' + newParent.userImage.split(".")[2];
                        } else {
                            temp5.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                        }
                        if (parent.children[p].children[q].children && parent.children[p].children[q].children.length > 0) {
                            var loop13 = parent.children[p].children[q].children;
                            for (var r = 0; r < loop13.length; r++) {
                                var newParent1 = parent.children[p].children[q].children[r];
                                if (newParent1) {
                                    var temp6 = {name: "", title: "", contact: ""};
                                    temp6.id = newParent1._id;
                                    temp6.userId = newParent1.user;
                                    temp6.name = newParent1.userName;
                                    var x = util.getFormattedDate(newParent1.createdAt);
                                    x = x.replace("-", "/");
                                    x = x.replace("-", "/");
                                    temp6.title = x;
                                    var y = newParent1.keyword.join(', ');
                                    temp6.contact = '[' + y + ']';
                                    var temp7 = {};
                                    temp7.text = temp6;
                                    temp7.stackChildren = false;
                                    temp7.children = [];
                                    temp7.callMe = newParent1.callMe;
                                    if (newParent1.userImage) {
                                        temp7.image = process.env.PROFILE_URL + newParent1.userImage.split(".")[1] + '.' + newParent1.userImage.split(".")[2];
                                    } else {
                                        temp7.image = process.env.PROFILE_URL + "/profileUploads/default.png";
                                    }
                                    if (parent.children[p].children[q].children[r].children && parent.children[p].children[q].children[r].children.length > 0) {

                                        var loop14 = parent.children[p].children[q].children[r].children;
                                    } else {
                                        parent.children[p].children[q].children[r].children = [];
                                    }
                                    temp5.children.push(temp7);
                                }
                            }
                        } else {
                            parent.children[p].children[q].children = [];
                        }
                        temp3.children.push(temp5);
                    }
                } else {
                    parent.children[p].children = [];
                }
                temp.children.push(temp3);
            }
        } else {
            parent.children = [];
        }
    }
    return temp;
};